package controllers.manage.room;

import build.OrderBuilder;
import build.OrderItemBuilder;
import controllers.BaseController;
import controllers.auth.Secure;
import enums.GoodsType;
import enums.OrderType;
import enums.TimingStatus;
import goods.Goods;
import helper.AliyunOssUploader;
import helper.GlobalConfig;
import jodd.util.StringUtil;
import models.AdminSupplier;
import models.admin.AdminUser;
import models.constants.DeletedStatus;
import models.merchant.Merchant;
import models.venue.enums.ChargeMode;
import models.venue.enums.OccupiedStatus;
import models.venue.policy.Policy;
import models.venue.room.Room;
import models.weixin.WebUser;
import net.sf.ehcache.search.expression.Or;
import order.Order;
import order.OrderItem;
import play.Logger;
import play.modules.paginate.JPAExtPaginator;
import play.mvc.Controller;
import play.mvc.With;
import util.common.DateUtil;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 包房管理
 * Created by hanbin on 17/4/6.
 */
@With(BaseController.class)
public class RoomCtrl extends Controller{

    /**
     * 跳转到包房管理页面
     */
    public static void index(Integer pageNumber, String roomName , Long supplierId){

        Merchant merchant = Secure.getLoginUser().merchant;
        List<AdminSupplier> supplierList = AdminSupplier.loadAllSupplier();

        pageNumber = pageNumber == null ? 1 : pageNumber;
        Map<String , Object> searchMap = new HashMap<>();

        if(StringUtil.isNotBlank(roomName)) {
            searchMap.put("roomName", "%"+roomName+"%");
        }

        if(merchant != null){
            searchMap.put("merchantId", merchant.id);
        }

        if(supplierId != null){
            searchMap.put("supplierId", supplierId);
        }

        flash.put("menuId", "5");

        JPAExtPaginator<Room> resultPage = Room.findByCondition(searchMap, "id desc", pageNumber, GlobalConfig.PAGE_SIZE);
        render(resultPage, pageNumber, roomName , supplierId , supplierList);
    }

    /**
     * 跳转到包房管理页面
     */
    public static void plane(){

        Merchant merchant = Secure.getLoginUser().merchant;

        // ------测试
        if(merchant == null) merchant = Merchant.findById(1l);

        List<Room> roomList = Room.findAllRoomByMerchant(merchant.id);

        for(Room room : roomList){
            room.occupiedStatus = OccupiedStatus.NOT_OCCUPIED;

            room.toolTip = buildToolTip(room.id);

            rebuildRoom(room);
        }

        flash.put("menuId", "6");

        render(roomList);
    }

    private static String buildToolTip(long roomId){
        String toolTip = "";
        List<Map<String,Object>> goodses = Goods.findByRoom(roomId);
        if(goodses.size() > 0){
            int i = 0;
            for(Map<String,Object> goods : goodses){
                if(i > 0) toolTip += "<br/><br/>";

                String start = DateUtil.dateToString(DateUtil.stringToDate(goods.get("begin_at").toString(), "yyyy-MM-dd HH:mm:ss"), "yyyy.MM.dd HH:mm:ss");
                String end = "";
                if(goods.get("endAt") == null){
                    end = "上机中...";
                }else{
                    end = DateUtil.dateToString(DateUtil.stringToDate(goods.get("endAt").toString(), "yyyy-MM-dd HH:mm:ss"), "yyyy.MM.dd HH:mm:ss");
                }

                toolTip += start + "&nbsp;&nbsp;-&nbsp;&nbsp;" + end;
                i ++;
            }
        }else{
            toolTip = "今日暂无";
        }
        return "<br/>" + toolTip + "<br/><br/>";
    }

    private static void rebuildRoom(Room room){
        List<OrderItem> orderItems =  OrderItem.findAllItemByGoodSerialId(room.id);
        if(orderItems != null){
            String now = DateUtil.dateToString(new Date(), "yyyyMMddHHmmss");
            for(OrderItem orderItem : orderItems){
                if(room.occupiedStatus == OccupiedStatus.BE_OCCUPIED){
                    break;
                }
                Room compareRoom = Room.findById(orderItem.goods.serialId);
                String goodName = orderItem.goods.name;
                if(room.id == compareRoom.id && goodName.contains("SPORTS_ROOMS")) {
                    goodName = goodName.split("_")[3];
                    String start = goodName.substring(0, 8) + goodName.substring(8, 12) + "00";
                    String end = goodName.substring(0, 8) + goodName.substring(12) + "00";
                    if (now.compareTo(start) > 0 && now.compareTo(end) < 0) {
                        room.occupiedStatus = OccupiedStatus.BE_OCCUPIED;
                    }
                }
            }
        }
    }

    /**
     * 跳转到新增包房页面
     */
    public static void add(){
        render();
    }

    /**
     * 跳转到修改包房页面
     */
    public static void modify(long id, Integer pageNumber){
        Room room = Room.findById(id);
        render(room, pageNumber);
    }


    /**
     * 创建包房
     */
    public static void create(Room room , File roomImage){

        Merchant merchant = Secure.getLoginUser().merchant;
        room.merchant = merchant;

        try {
            if(roomImage != null) {
                BufferedImage sourceImg = ImageIO.read(new FileInputStream(roomImage));
                Integer width = sourceImg.getWidth();
                Integer height = sourceImg.getHeight();
//                if(((double)width/(double)height) != ((double)4/(double)3)){
//                    room.deleted = DeletedStatus.UN_DELETED;
//                    room.save();
//                    flash.put("msg" , "图片比例不是4:3");
//                    modify(room.id, 1);
//                }
                room.roomImage = AliyunOssUploader.uploadPublicFile(roomImage , 300);
            }
            room.deleted = DeletedStatus.UN_DELETED;
            room.save();
            flash.put("msg" , "包房创建成功");
            redirect("/BS0009/admin/room/index/1");
        } catch (Exception e) {
            Logger.warn(e, "LOG01750: room create failed!");
        }
    }

    /**
     * 修改包房
     */
    public static void update(Long id, Room room, Integer pageNumber, File roomImage){
        try {
            if(roomImage != null) {
                BufferedImage sourceImg = ImageIO.read(new FileInputStream(roomImage));
                Integer width = sourceImg.getWidth();
                Integer height = sourceImg.getHeight();
                if(((double)width/(double)height) != ((double)4/(double)3)){
                    Room.update(id , room);
                    flash.put("msg" , "图片比例不是4:3");
                    modify(id, pageNumber);
                }
                room.roomImage = AliyunOssUploader.uploadPublicFile(roomImage , 300);
            }
            Room.update(id , room);
            flash.put("msg" , "包房修改成功");
            redirect("/BS0009/admin/room/index/"+pageNumber);
        } catch (Exception e) {
            Logger.warn(e, "LOG01750: room update failed!");
        }
    }

    /**
     * 删除包房
     */
    public static void delete(long id , Integer pageNumber){
        pageNumber = pageNumber == null ? 1 : pageNumber;
        Room room = Room.findById(id);
        room.deleted=DeletedStatus.DELETED;
        room.save();
        flash.put("msg" , "包房删除成功");
        redirect("/BS0009/admin/room/index/"+pageNumber);
    }

    /**
     * 房间预定
     */
    public static void book(String phone){
        Merchant merchant = Secure.getLoginUser().merchant;
        // ------测试
        if(merchant == null) merchant = Merchant.findById(1l);

        List<Order> orders = Order.findTimingStartOrders(merchant.id, phone);
        for(Order order : orders){
            List<OrderItem> orderItems = OrderItem.findByOrder(order);
            if(orderItems != null && orderItems.size() > 0) {
                Goods goods = orderItems.get(0).goods;
                if(goods != null) {
                    Room room = Room.findById(goods.serialId);
                    if(room != null) {
                        order.proName = room.roomName;
                        if(room.chargeMode == ChargeMode.MINUTE){
                            order.proName += "  计费模式:分钟";
                        }else if(room.chargeMode == ChargeMode.TEN_MINUTE){
                            order.proName += "  计费模式:十分钟";
                        }else if(room.chargeMode == ChargeMode.HALF_HOUR){
                            order.proName += "  计费模式:半小时";
                        }else if(room.chargeMode == ChargeMode.HOUR){
                            order.proName += "  计费模式:小时";
                        }
                        order.roomId = room.id+"";
                    }
                }
            }
        }

        List<Room> rooms = Room.findAllRoomByMerchant(merchant.id);
        for(Room room : rooms){
            if(room.chargeMode == ChargeMode.MINUTE){
                room.roomName += "  计费模式:分钟";
            }else if(room.chargeMode == ChargeMode.TEN_MINUTE){
                room.roomName += "  计费模式:十分钟";
            }else if(room.chargeMode == ChargeMode.HALF_HOUR){
                room.roomName += "  计费模式:半小时";
            }else if(room.chargeMode == ChargeMode.HOUR){
                room.roomName += "  计费模式:小时";
            }
        }

        flash.put("menuId", "roomBook");

        render(orders, rooms, phone);
    }

    /**
     * 开始计时
     */
    public static void createBook(String phone, long id){
        WebUser webUser = WebUser.findByPhone(phone);
        if(webUser == null) {
            flash.put("msg" , "没找到用户");
            redirect("/BS0012/admin/room/book");
        }
        Room room = Room.findById(id);
        AdminUser adminUser = Secure.getLoginUser();
        // 生成订单
        OrderBuilder orderBuilder = OrderBuilder.forBuild().byUser(webUser).type(OrderType.PC).merchant(adminUser.merchant).goodsType(GoodsType.SPORTS_ROOMS);
        Order order = orderBuilder.save();

        Goods goods = Goods.findOrCreateTypeTimeGoodsForRoom2(GoodsType.SPORTS_ROOMS , room);
        goods.serialId = id;

        // 添加订单内容
        OrderItemBuilder orderItemBuilder = orderBuilder.addGoods(goods);
        orderItemBuilder
                .amount(0d)
                .salePrice(0d);
        orderBuilder.changeToUnPaid();
        orderItemBuilder.build();

        order.timingStatus = TimingStatus.START;
        order.save();

        flash.put("msg" , "包房计时开始");
        redirect("/BS0012/admin/room/book");
    }

    /**
     * 结束计时
     */
    public static void endTimeing(long id, long roomId){
        Order order = Order.findById(id);
        Room room = Room.findById(roomId);

        if(order == null){
            flash.put("msg" , "没找到订单");
            redirect("/BS0012/admin/room/book");
        }

        if(room == null){
            flash.put("msg" , "没找到包房");
            redirect("/BS0012/admin/room/book");
        }

        Date start = order.createdAt;
        Date end = new Date();
        Double amount = 0d;
        Integer hours = DateUtil.differenceHours(start , end).intValue();
        Logger.info("Hours : %s" , hours);
        hours = hours == 0 ? 1 : hours;
        for(int i = 0 ; i < hours ; i ++) {
            //获取开始时间  11:20
            String beginTime = DateUtil.dateToString(start , "HH:mm");
            //获取当前小时 11
            String startHH = DateUtil.dateToString(start , "HH"); // 10
            String startmm = DateUtil.dateToString(start , "mm"); // 5

            // 获取 结束时间 (11+1):00  用来计算收费价格
            String endTime = (Integer.valueOf(startHH) +1)+":00";  // 11:00
            Logger.info("BeginTime : %s | endTime : %s" , beginTime, endTime);
            Policy policy = Policy.findByRoomAndBeginTimeAndEndTime(room, beginTime, endTime);
            if(i == 0 || hours == (i+1) ) {
                Integer minus = 0;
                if(hours == 1 || i == hours -1) {
                    String oneEndTime = DateUtil.dateToString(new Date() , "mm");
                    minus = (Integer.parseInt(oneEndTime) == 0 ? 60 :Integer.parseInt(oneEndTime))  - Integer.parseInt(startmm);
                } else  {
                    minus = 60;
                }
                Logger.info("Minus : %s" , minus);
                if(room.chargeMode == ChargeMode.MINUTE) {
                    amount += (minus * policy.price.doubleValue()) / 60;
                }
                if(room.chargeMode == ChargeMode.TEN_MINUTE) {
                    Integer min = minus%10 == 0 ? minus/10 : minus/10 +1;
                    Logger.info("TEN_MINUTE.min : %s" , min);
                    amount += (min * 10 * policy.price.doubleValue()) / 60;
                }
                if(room.chargeMode == ChargeMode.HALF_HOUR) {
                    Integer min = minus%30 == 0 ? minus/30 : minus/30 +1;
                    Logger.info("HALF_HOUR.min : %s" , min);
                    amount += (min * 30 * policy.price.doubleValue()) / 60;
                }
                if(room.chargeMode == ChargeMode.HOUR) {
                    amount += policy.price.doubleValue();
                }
            } else {
                amount += policy.price.doubleValue();
            }
            start = DateUtil.stringToDate(endTime , "HH:mm");
        }

        order.amount = amount;


//        String roomStart = DateUtil.dateToString(start, "HH:mm");
//        String roomEnd = DateUtil.dateToString(end, "HH:mm");
//
//        List<Policy> policies = Policy.findRoomPolicyForOffline(room, roomStart, roomEnd);
//        if(policies == null || policies.size() <= 0){
//            flash.put("msg" , "没找到包房价格策略");
//            redirect("/BS0012/admin/room/book");
//        }
//
//        int unit = 0;// 计时单位
//        int munit = 0;// 计价单位
//
//        if(room.chargeMode == ChargeMode.MINUTE){
//            unit = 1;
//            munit = 60;
//        }else if(room.chargeMode == ChargeMode.TEN_MINUTE){
//            unit = 10;
//            munit = 6;
//        }else if(room.chargeMode == ChargeMode.HALF_HOUR){
//            unit = 30;
//            munit = 2;
//        }else if(room.chargeMode == ChargeMode.HOUR){
//            unit = 60;
//            munit = 1;
//        }
//        if(unit == 0) {
//            flash.put("msg" , "包房没有设置收费模式");
//            book(null);
//        }
//
//        String realStart = "";
//        String realEnd = "";
//        int rate;
//        for(Policy policy : policies){
//            realStart = DateUtil.dateToString(end, "yyyy-MM-dd");
//            realEnd = DateUtil.dateToString(end, "yyyy-MM-dd");
//
//            String policyStart = policy.startTime;
//            String policyEnd = policy.endTime;
//            if(roomStart.compareTo(policyStart) > 0){
//                realStart += " " + roomStart + ":00";
//            }else{
//                realStart += " " + policyStart + ":00";
//            }
//            if(roomEnd.compareTo(policyEnd) > 0){
//                realEnd += " " + policyEnd + ":00";
//            }else{
//                realEnd += " " + roomEnd + ":00";
//            }
//
//            Long s = (DateUtil.stringToDate(realEnd, "yyyy-MM-dd HH:mm:ss").getTime() - DateUtil.stringToDate(realStart, "yyyy-MM-dd HH:mm:ss").getTime())/ (1000 * 60); //分钟
//
//            if(s%unit != 0){
//                rate = Integer.valueOf((s/unit + 1)+"");
//            }else{
//                rate = Integer.valueOf(s/unit + "");
//            }
//
//
//
//            order.amount += policy.price.divide(new BigDecimal(munit) , 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(rate)).doubleValue();
//        }
        order.remark = "包房名称:" + room.roomName + ". 上机时间:" + DateUtil.dateToString(order.createdAt , "yyyy-MM-dd HH:mm") + "。下机时间:" + DateUtil.dateToString(new Date() , "yyyy-MM-dd HH:mm") +".共消费:" + amount +"元";
        order.timingStatus = TimingStatus.END;
        order.save();

        List<OrderItem> orderItems = OrderItem.findByOrder(order);
        for(OrderItem orderItem : orderItems) {
            orderItem.salePrice = order.amount;
            orderItem.save();
            Goods goods = orderItem.goods;
            goods = Goods.findById(goods.id);
            goods.salePrice = order.amount;
            goods.endAt = new Date();
            goods.save();
        }
        flash.put("msg" , "包房计时结束");
        redirect("/BS0023/admin/order/detail/"+order.id+"/1");
    }

}
